package gui

import (
	"fmt"
	"path/filepath"
	"strings"

	"downloader/internal/crawler"
	"downloader/internal/downloader"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/widget"
)

type GUI struct {
	app    fyne.App
	window fyne.Window

	// 下载相关组件
	urlEntry    *widget.Entry
	outputEntry *widget.Entry
	progressBar *widget.ProgressBar
	downloadBtn *widget.Button
	statusLabel *widget.Label

	// 爬虫相关组件
	crawlURLEntry    *widget.Entry
	depthEntry       *widget.Entry
	crawlOutputEntry *widget.Entry
	crawlBtn         *widget.Button
	crawlStatus      *widget.Label
}

// New 创建并返回一个新的 GUI 实例
func New() *GUI {
	return &GUI{}
}

// Start 初始化并启动 GUI
func (g *GUI) Start() {
	g.app = app.New()
	g.window = g.app.NewWindow("Universal Downloader")

	// 创建主界面
	g.createUI()

	// 设置窗口大小并显示
	g.window.Resize(fyne.NewSize(800, 600))
	g.window.ShowAndRun()
}

func (g *GUI) createUI() {
	// 创建下载标签页
	downloadTab := container.NewVBox(
		widget.NewLabel("下载链接:"),
		g.urlEntry,
		widget.NewLabel("保存目录:"),
		g.outputEntry,
		g.progressBar,
		g.statusLabel,
		g.downloadBtn,
	)

	// 创建爬虫标签页
	crawlerTab := container.NewVBox(
		widget.NewLabel("网站URL:"),
		g.crawlURLEntry,
		widget.NewLabel("爬取深度:"),
		g.depthEntry,
		widget.NewLabel("输出文件:"),
		g.crawlOutputEntry,
		g.crawlStatus,
		g.crawlBtn,
	)

	// 创建标签页容器
	tabs := container.NewAppTabs(
		container.NewTabItem("下载器", downloadTab),
		container.NewTabItem("网站爬虫", crawlerTab),
	)
	tabs.SetTabLocation(container.TabLocationTop)

	g.window.SetContent(tabs)
}

func (g *GUI) startDownload() {
	url := g.urlEntry.Text
	if url == "" {
		dialog.ShowError(fmt.Errorf("请输入下载链接"), g.window)
		return
	}

	// 禁用下载按钮
	g.downloadBtn.Disable()
	g.statusLabel.SetText("正在下载...")

	// 创建下载配置
	config := &downloader.Config{
		MaxThreads: 4,
		OutputDir:  g.outputEntry.Text,
	}

	// 创建下载器
	dl, err := downloader.New(detectProtocol(url), config)
	if err != nil {
		dialog.ShowError(err, g.window)
		g.downloadBtn.Enable()
		return
	}

	// 启动下载
	go func() {
		err := dl.Download(url)
		if err != nil {
			g.app.SendNotification(fyne.NewNotification("下载失败", err.Error()))
			g.statusLabel.SetText("下载失败: " + err.Error())
		} else {
			g.app.SendNotification(fyne.NewNotification("下载完成", filepath.Base(url)))
			g.statusLabel.SetText("下载完成")
		}
		g.downloadBtn.Enable()
	}()

	// 更新进度
	go func() {
		for {
			progress := dl.Progress()
			g.progressBar.SetValue(progress / 100)
			if progress >= 100 {
				break
			}
		}
	}()
}

func (g *GUI) startCrawling() {
	url := g.crawlURLEntry.Text
	if url == "" {
		dialog.ShowError(fmt.Errorf("请输入网站URL"), g.window)
		return
	}

	// 禁用爬取按钮
	g.crawlBtn.Disable()
	g.crawlStatus.SetText("正在爬取...")

	// 创建爬虫配置
	config := crawler.Config{
		MaxDepth: 3, // 可以从depthEntry获取
		URLFile:  g.crawlOutputEntry.Text,
	}

	// 创建爬虫
	c, err := crawler.New(url, config)
	if err != nil {
		dialog.ShowError(err, g.window)
		g.crawlBtn.Enable()
		return
	}

	// 启动爬取
	go func() {
		if err := c.Start(); err != nil {
			g.app.SendNotification(fyne.NewNotification("爬取失败", err.Error()))
			g.crawlStatus.SetText("爬取失败: " + err.Error())
		} else {
			if err := c.Finalize(); err != nil {
				g.app.SendNotification(fyne.NewNotification("保存结果失败", err.Error()))
			} else {
				g.app.SendNotification(fyne.NewNotification("爬取完成", "结果已保存到 "+config.URLFile))
				g.crawlStatus.SetText("爬取完成")
			}
		}
		g.crawlBtn.Enable()
	}()
}

func detectProtocol(urlStr string) string {
	// 简单的协议检测
	if strings.HasPrefix(urlStr, "magnet:") {
		return "magnet"
	} else if strings.HasPrefix(urlStr, "ed2k://") {
		return "ed2k"
	} else if strings.HasPrefix(urlStr, "ftp://") {
		return "ftp"
	} else if strings.HasPrefix(urlStr, "sftp://") {
		return "sftp"
	} else if strings.HasSuffix(urlStr, ".torrent") {
		return "torrent"
	}
	return "http"
}

// 使用说明：
// 1. 在主程序（例如 main.go）中导入这个包：
//    import "path/to/gui"
//
// 2. 在 main 函数中创建 GUI 实例并启动：
//    func main() {
//        g := gui.New()
//        g.Start()
//    }
//
// 3. 确保主程序位于项目根目录，并且 go.mod 文件正确配置了所有依赖
//
// 4. 运行主程序：
//    go run main.go
